#if !defined(__HASH_H__)
#define __HASH_H__

#include <cstdlib>

namespace tagfolder{

    /**
     * Common interface for hash Algorithm;
     */
    template< typename T>
    class HashAlg{
        public: 
            virtual unsigned long operator () ( T ) = 0;
    };

    /**
     * SDB Hash
     */
    class SDBHash: public HashAlg< const char*>{
        public:
            virtual unsigned long operator () ( const char* );
    };

    /**
     * RS Hash
     */
    class RSHash: public HashAlg< const char*>{
        public:
            virtual unsigned long operator () ( const char* );
    };

    /**
     * JS Hash
     */
    class JSHash: public HashAlg< const char*>{
        public:
            virtual unsigned long operator () ( const char* );
    };

    /**
     *  P. J. Weinberger Hash
     */
    class PJWHash: public HashAlg< const char*>{
        public:
            virtual unsigned long operator() ( const char* );
    };

    /**
     * ELF Hash
     */
    class ELFHash: public HashAlg< const char*>{
        public:
            virtual unsigned long operator() ( const char* );
    };

    /**
     * AP Hash
     */
    class APHash: public HashAlg< const char*>{
        public:
            virtual unsigned long operator() ( const char* );
    };

    /**
     * Hasher class;
     */
    class StringHasher{
        public:
            typedef HashAlg< const char*> StrHashAlg;
            typedef StrHashAlg* StrHashAlgPtr;
        public:
            static StringHasher& getInstance(){
                if( m_instance==NULL){
                    m_instance=new StringHasher();
                }
                return (*m_instance);
            }

            virtual unsigned long makeHash( const char* );
            virtual ~StringHasher();
        private:
            StringHasher();
            static StringHasher* m_instance;
            StrHashAlgPtr* m_alg;
            size_t m_algCount;
    };
}

#endif
